//udp服务端(udp天生支持多客户端)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
#include <pthread.h>

int pack_cnt=0;
int pack_err=0;
int pack_disorder=0;
int daikuang=0;
pthread_t pt_id;
int n,old_n = 0;

void *printf_info(void *arg);

int main(int argc, char const *argv[])
{
	int i;
	
	socklen_t len;
	char buf[1024];

	struct sockaddr_in serv;
	struct sockaddr_in client;

	//1.创建socket
	int cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd<0){
		perror("socket error");
		return -1;
	}

	//绑定
	bzero(&serv,sizeof(serv));
	serv.sin_family = AF_INET;
	serv.sin_port = htons(9999);
	serv.sin_addr.s_addr = htonl(INADDR_ANY);
	bind(cfd,(struct sockaddr *)&serv,sizeof(serv));

	pthread_create(&pt_id,NULL,printf_info,NULL);
	pthread_detach(pt_id);	//线程分离	自动回收资源

	//3.循环读取读取客户端消息和给客户端回复消息
	while(1){
		//4.读取数据
		memset(buf,0x00,sizeof(buf));
		len = sizeof(client);
		n = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&client,&len);

		buf[16] = 0;
		daikuang+=n;
		
		{
			int p;
			n=0;
			for(p=4;p<16;p++)
			{
				n*=10;
				n+=buf[p]-'0';
				if(buf[p+1]==' ')
					break;
			}
		}
		pack_cnt++;
		if(!(n == old_n+1))
		{
			if(n>=old_n+2) pack_err++;//丢包了
			else if(n<=old_n) pack_disorder+1;//乱序包
		}
		
		old_n = n;
		//printf("buf=%s\n",buf);

		//5.给客户端回复消息
		//sendto(cfd,"AAA\n",n,0,(struct sockaddr*)&client,4);
	}
	//关闭套接字
	close(cfd);

	return 0;
}

void *printf_info(void *arg)
{
	while (1)
	{
		sleep(1);
		printf("收包:%d,错报:%d,乱序包:%d,带宽:%dB/s,合计%0.2fKB/s\n",pack_cnt,pack_err,pack_disorder,daikuang,((float)daikuang)/1024);
		daikuang=0;
	}
	return 0;
}